package mysupertux.game;

import org.lwjgl.input.Keyboard;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;

public class GameConfiguration {
	/** Total number of actions. Actions IDs go from 0 .. ACTIONS_COUNT-1. */
	public static final int ACTIONS_COUNT = 2;

	public static int ACTION_MOVE_LEFT = 0;
	public static int ACTION_MOVE_RIGHT = 1;

	/** ACTION_ -> String */
	private static HashMap<Integer, String> action2string = new HashMap<Integer, String>();

	static {
		action2string.put(new Integer(ACTION_MOVE_LEFT), "ACTION_MOVE_LEFT");
		action2string.put(new Integer(ACTION_MOVE_RIGHT), "ACTION_MOVE_RIGHT");

		// prevent missing action strings
		if (action2string.size() != ACTIONS_COUNT) {
			System.out
					.println("Error in GameConfiguration: missing action string.");
		}
	}

	/** Key bindings: action2key[ACTION_] = Keyboard.KEY_ */
	private static int action2key[] = new int[ACTIONS_COUNT];

	static {
		loadFrom("default.config");
	}

	/**
	 * Returns the name of the given action id.
	 * 
	 * @param action
	 *            action id
	 * @return name of the action
	 */
	public static String getActionName(int action) {
		return (String) action2string.get(new Integer(action));
	}

	/**
	 * Returns the action id for the given action name.
	 * 
	 * @param name
	 *            action name
	 * @return id of the action
	 */
	public static int getActionID(String name) {
		Iterator<Integer> keysIterator = action2string.keySet().iterator();
		while (keysIterator.hasNext()) {
			Integer actionID = keysIterator.next();
			if (action2string.get(actionID).equals(name))
				return actionID.intValue();
		}
		throw new RuntimeException(
				"Error in GameConfiguration.getActionID(): no such action name.");
	}

	/**
	 * Returns the key for the given action id.
	 * 
	 * @param action
	 *            action id
	 * @return Keyboard.KEY_...
	 */
	public static int getKey(int action) {
		return action2key[action];
	}

	/**
	 * Loads the GameConfiguration from the given file.
	 * 
	 * @param fileName
	 *            file name
	 */
	public static void loadFrom(String fileName) {
		Properties properties = new Properties();

		// load from file
		try {
			InputStream in = new FileInputStream("config/" + fileName);
			properties.load(in);
		} catch (IOException e) {
			System.out
					.println("Error in GameConfiguration.loadFrom(): could not load from file config/"
							+ fileName);
			return;
		}

		// restore key bindings
		for (int actionID = 0; actionID < ACTIONS_COUNT; actionID++) {
			String keyName = (String) properties.get(getActionName(actionID));
			if (keyName == null)
				continue;

			action2key[actionID] = Keyboard.getKeyIndex(keyName);
		}
	}

	/**
	 * Saves the GameConfiguration to the given file.
	 * 
	 * @param fileName
	 *            file name
	 */
	public static void saveTo(String fileName) {
		Properties properties = new Properties();

		// store key bindings
		for (int actionID = 0; actionID < ACTIONS_COUNT; actionID++) {
			properties.put(getActionName(actionID), Keyboard
					.getKeyName(getKey(actionID)));
		}

		// write to file
		try {
			OutputStream out = new FileOutputStream("config/" + fileName);
			properties.store(out, "GameConfiguration");
		} catch (IOException e) {
			System.out
					.println("Error in GameConfiguration.saveTo(): could not write to file config/"
							+ fileName);
			return;
		}
	}
}
